﻿using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using BI.Commons.ExtensionMethods;
using BankInvest.InstrumentEditor.Domain.Entities;
using BankInvest.InstrumentEditor.Domain.Repositories;
using BankInvest.InstrumentEditor.NHibernate;

namespace BankInvest.InstrumentEditor.Controllers
{
    public class InstrumentEditorController : IDisposable
    {
        private readonly IInstrumentEditorView _instrumentEditorView;
        private readonly IInstrumentTypeRepository _instrumentTypeRepository;
        private readonly IInstrumentRepository _instrumentRepository;
        private IUnitOfWork _unitOfWork;

        public InstrumentEditorController(IInstrumentEditorView instrumentEditorView,
                                          IInstrumentTypeRepository instrumentTypeRepository,
                                          IInstrumentRepository instrumentRepository, 
                                          IUnitOfWork unitOfWork)
        {
            _instrumentEditorView = instrumentEditorView;
            _instrumentTypeRepository = instrumentTypeRepository;
            _instrumentRepository = instrumentRepository;
            _unitOfWork = unitOfWork;

            _instrumentEditorView.Save += AddOrMerge;
            _instrumentEditorView.FindById += Find;
        }

        private void Find()
        {
            var instrument = _instrumentRepository.Get(_instrumentEditorView.Id);

            Display(instrument);
        }

        private void Display(Instrument instrument)
        {
            _instrumentEditorView.Id = instrument.Id;
            _instrumentEditorView.InstrumentName = instrument.Name;
            _instrumentEditorView.IsActive = instrument.IsActive;
            _instrumentEditorView.SelectedInstrumentTypeId = instrument.Type.Id;

            _instrumentEditorView.Status = "Instrument \"{0}\" found.".FormatWith(instrument.Id);
        }

        private void AddOrMerge()
        {
            _instrumentRepository.AddOrMerge(new Instrument
            {
                Id = _instrumentEditorView.Id,
                Name = _instrumentEditorView.InstrumentName,
                Type = new InstrumentType(_instrumentEditorView.SelectedInstrumentTypeId),
                IsActive = _instrumentEditorView.IsActive
            });

            _unitOfWork.Commit();

            _instrumentEditorView.Status = "Instrument \"{0}\" successfully saved.".FormatWith(_instrumentEditorView.Id);
        }

        public void InitializeInstrumentEditorView()
        {
            _instrumentEditorView.InstrumentTypeIdNameDictionary = 
                _instrumentTypeRepository.GetAll().ToDictionary(it => it.Id, it => it.Name);

            _instrumentEditorView.IsActive = true;
        }

        [ExcludeFromCodeCoverage]
        public IInstrumentEditorView GetInitializedView()
        {
            InitializeInstrumentEditorView();

            return _instrumentEditorView;
        }

        public void Dispose()
        {
            _unitOfWork.Dispose();
        }
    }
}